import { IUploadFormCommonProps } from './type';
import { Col, Button, message, Form, Input, Upload, Row, Tooltip, Popconfirm } from 'antd';
import { QuestionCircleOutlined, EyeOutlined } from '@ant-design/icons';
import React, { useState, Fragment, useEffect, useMemo, useCallback } from 'react';
import { UploadOutlined, DeleteOutlined } from '@ant-design/icons';
import { getBaseUrl } from '@/services/urlconst';
import { downloadTemplate, downloadTemplatePost, getTenant } from '@/utils';
import fileBoxStyle from './styles.less';
import pageStyles from '@/common/pageLayout.less';
import _ from 'lodash';
import Cls from 'classnames';

const baseUrl = getBaseUrl();
// const baseUrl = 'wenchuang';

// const baseUrl = '/xc';
// const baseUrl = 'http://222.186.101.211:20103'; //线上地址

/**
 * 表单上传文件 公共组件
 * @param form  表单 form
 * @param name  表单 name
 * @param label  表单 label
 * @param required  表单 是否必传 required
 * @param accept 上传文件类型
 * @param url 上传文件类型
 * @param defaultFiles 初始值
 * @param downloadUrl 下载接口
 * @param fileFormName 文件存放 表单 名字
 * @param fileFormDelName 文件存放 删除 表单 名字
 * @param tip 上传提示
 * @param maxFile 文件上传个数 ,默认 一直传
 * @param spanCol col 所占栅格
 * @param inRowProportion 每个文件展示的 所占 col , 按照布局自己算好, 例如: spanCol= 12; inRowProportion =24 || spanCol= 24;inRowProportion=8
 * @param delFunc 删除文件回调
 * @param uploadSuccessCallback 上传成功回调函数
 */

export const UploadFormCommon: React.FC<IUploadFormCommonProps> = ({
  form,
  name,
  label,
  required,
  accept = '.db',
  url,
  defaultFiles,
  downloadUrl,
  fileFormName,
  fileFormDelName,
  maxFile,
  spanCol,
  inRowProportion,
  delFunc,
  uploadSuccessCallback,
  isMultiple = true,
  children,
  tip,
  downloadMethod,
  isEdit = false,
  classname = '',
  hintTitle = '若需更换，请删除多余文件！',
  // hintTitle = "若超过文件个数限制，将保存最新上传的文件！",
  disabledUpload = false,
  filedTypeTable = false,
  fieldBusiPath = '',
  onChangeFormValues,
  onNtkoRead,
  onOpenReadOfdWord,
}) => {
  /**
   * 文件列表
   */
  const [fileList, setFileList] = useState<any>([]);
  const fileCallback = useCallback(
    (fileArr: any) => {
      setFileList(fileArr);
    },
    [fileList],
  );
  const [delfilePaths, setDelfilePaths] = useState<string>('');

  /**
   * 上传按钮loading
   */
  const [uploadLoading, setUploadLoading] = useState<boolean>(false);

  /** 保存文件类型 */
  const [saveFieldType, setSaveFieldType] = useState<string>('');

  useEffect(() => {
    if (defaultFiles) {
      renderFileList(defaultFiles);
    } else {
      fileCallback([]);
    }
  }, [defaultFiles]);

  /**
   * 初始化渲染,
   * @param defaultFiles 初始化文件路径
   */
  const renderFileList = (defaultFiles: string) => {
    if (defaultFiles) {
      let defauFileArr: any = [];
      let attachmentPath = defaultFiles?.split('||');
      attachmentPath?.forEach((item: any) => {
        let path = item.split('^^');
        let fileType: string = item.split('.')?.[1]; //获取文件类型
        let name: string = ''; //文件名称
        let url: string = ''; //文件路径
        let original: string = '';
        if (path[1]) {
          original = path[1];
          name = path[1];
          url = path[0];
        } else {
          path = item.split('/');
          name = path[path.length - 1];
          url = item;
        }
        let attach = {
          uid: item + '',
          name,
          url,
          status: 'done',
          fileType: '.' + fileType,
          fileState: 'SUCCESS',
        };
        defauFileArr.push(attach);
      });
      fileCallback(defauFileArr);
    }
  };

  /**
   * 限制上传文件类型
   * @param file 文件对象
   * @param accept 文件类型
   * @returns
   */
  const isTypeCorrect = (file: any, accept: string) => {
    let name = file.name;
    let arr = [`.${name.split('.').pop().toLowerCase()}`]; // 取后缀名

    /** 保存上传文件类型 */
    setSaveFieldType(arr?.toString());

    if (accept) {
      let acceptArr = accept.split(',');

      // let isCorrect = false;
      let isCorrect: boolean = acceptArr?.some((item: any) => {
        return arr.includes(String(item));
      });

      // for (let i = 0; i < acceptArr.length; i++) {
      //   if (arr.includes(String(acceptArr[i]))) {
      //     isCorrect = true;
      //   }
      // }
      return isCorrect;
    } else {
      if (arr.includes('.doc') || arr.includes('.docx') || arr.includes('.pdf') || arr.includes('.jpg')) {
        return true;
      } else {
        return false;
      }
    }
  };

  /** 表格改变数据 */
  const uploadTableHandle = (fieldStr: string) => {
    const formTableName: string = fileFormName?.[0];
    const formList: Record<string, any>[] = form?.getFieldValue(formTableName);
    const fileCode: string = fileFormName[2];
    formList[fileFormName[1]][fileCode] = fieldStr;
    // formList[fileFormName[1]][fileFormDelName] = fieldStr;
    form?.setFieldsValue({
      [formTableName]: formList,
    });
    if (onChangeFormValues) {
      onChangeFormValues({
        [formTableName]: formList,
      });
    }
  };

  /**
   * 文件改变
   * @param dataList 文件列表
   * @param delfileUrl 文件路径
   */
  const fileChange = (dataList: any, delfileUrl: any) => {
    let attachPaths = '';
    // if (isOnlyFile) {
    //   let file = dataList[dataList.length - 1];
    //   if (file.status == 'done') {
    //     let url = file.url;
    //     attachPaths = url;
    //   }
    //   dataList = [file];
    // } else {

    dataList?.forEach((item: any, index: number) => {
      if (item.status == 'done') {
        let url = item.url;
        let paths = url.split('/');
        if (item.original && item.original != paths[paths.length - 1]) {
          url = url + '^^' + item.original;
        }
        if (index == dataList.length - 1) {
          attachPaths = attachPaths + url;
        } else {
          attachPaths = attachPaths + url + '||';
        }
      }
    });
    // }

    let delfilePath: string = delfilePaths;
    if (delfileUrl) {
      if (delfilePath != '') {
        delfilePath = delfilePaths + '||' + delfileUrl;
      } else {
        delfilePath = delfileUrl;
      }
    }

    // if (fileChange) {
    //   fileChange(attachPaths, delfilePath);
    // }

    if (form) {
      if (filedTypeTable) {
        uploadTableHandle(attachPaths);
        // const formTableName: string = fileFormName?.[0];
        // const formList: Record<string, any>[] = form?.getFieldValue(formTableName);
        // const fileCode: string = fileFormName[2];
        // formList[fileFormName[1]][fileCode] = attachPaths;
        // formList[fileFormName[1]][fileFormDelName] = attachPaths;
        // form.setFieldsValue({
        //   [formTableName]: formList,
        // });
      } else {
        form.setFieldsValue({
          [fileFormName]: attachPaths,
          [fileFormDelName]: delfilePath,
        });
      }

      uploadSuccessCallback && uploadSuccessCallback(attachPaths);
    }
    setDelfilePaths(delfilePath);
    // let newDataList = deepClone(dataList);
    let newDataList = dataList;
    fileCallback(newDataList);
  };

  // /**
  //  * 获取文件图标
  //  * @param fileName 文件名字
  //  * @returns
  //  */
  // const getFileTypeIcon = (fileName: any) => {
  //   let type = '';
  //   if (
  //     fileName.endsWith('.jpg') ||
  //     fileName.endsWith('.png') ||
  //     fileName.endsWith('.psd') ||
  //     fileName.endsWith('.ai') ||
  //     fileName.endsWith('.tif') ||
  //     fileName.endsWith('.gif')
  //   ) {
  //     type = 'file_pic';
  //   } else if (fileName.endsWith('.zip')) {
  //     type = 'file_zip';
  //   } else if (fileName.endsWith('.docx') || fileName.endsWith('.doc')) {
  //     type = 'file_word_office';
  //   } else if (fileName.endsWith('.pdf')) {
  //     type = 'file_pdf';
  //   } else if (fileName.endsWith('.txt')) {
  //     type = 'file_txt';
  //   } else if (
  //     fileName.endsWith('.wmv') ||
  //     fileName.endsWith('.rmvb') ||
  //     fileName.endsWith('.mp4') ||
  //     fileName.endsWith('.3gp') ||
  //     fileName.endsWith('.m4v') ||
  //     fileName.endsWith('.mov') ||
  //     fileName.endsWith('.mkv') ||
  //     fileName.endsWith('.flv') ||
  //     fileName.endsWith('.asf') ||
  //     fileName.endsWith('.avi') ||
  //     fileName.endsWith('.mpg') ||
  //     fileName.endsWith('.rm')
  //   ) {
  //     type = 'file_video';
  //   } else if (fileName.endsWith('.wav') || fileName.endsWith('.mp3') || fileName.endsWith('.midi')) {
  //     type = 'file_music';
  //   } else if (
  //     fileName.endsWith('.xlsx') ||
  //     fileName.endsWith('.xlsm') ||
  //     fileName.endsWith('.xlsb') ||
  //     fileName.endsWith('.xltx') ||
  //     fileName.endsWith('.xltm') ||
  //     fileName.endsWith('.xls')
  //   ) {
  //     type = 'file_excel_office';
  //   } else {
  //     type = 'file_unknown';
  //   }
  //   return type;
  // };

  /**
   * 保留删除后已有的信息，用||连接
   * @param files 文件
   * @returns
   */
  const reserveAttachmentPath = (files: any) => {
    let attachmentPath = '';
    if (files.length > 1) {
      files?.forEach((item: any, index: number) => {
        if (index == files.length - 1) {
          attachmentPath += item?.url;
        } else {
          attachmentPath += item?.url + '||';
        }
      });
      return attachmentPath;
    } else {
      return files[0].url;
    }
  };

  /**
   * 返回文件名称处理
   * @param fileObj 文件对象
   * @returns
   */
  const getFileNameNotType = (fileObj: any) => {
    let arr = fileObj?.name?.split('.');
    let endType = arr.pop();
    let nameStr = arr.join('');
    if (inRowProportion == 6) {
      if (nameStr.length >= 6) {
        nameStr = nameStr.substr(0, 3) + '...' + nameStr.substr(-1);
      }
    }
    if (inRowProportion == 8) {
      if (nameStr.length >= 8) {
        nameStr = nameStr.substr(0, 5) + '...' + nameStr.substr(-1);
      }
    }
    if (inRowProportion == 12) {
      if (nameStr.length >= 12) {
        nameStr = nameStr.substr(0, 9) + '...' + nameStr.substr(-1);
      }
    }
    if (inRowProportion == 24) {
      if (nameStr.length >= 24) {
        nameStr = nameStr.substr(0, 16) + '...' + nameStr.substr(-1);
      }
    }

    return nameStr + `.${endType}`;
  };

  /**
   * 删除文件
   * @param fileObj 文件对象
   */
  const deleteFile = (fileObj: any) => {
    let newFileArr: any[] = fileList;
    let files: any[] = [];
    let attachmentPath: any = '';
    newFileArr?.forEach((item: any) => {
      if (item.uid != fileObj.uid) {
        files.push(item);
      }
    });

    if (files.length > 0) {
      attachmentPath = reserveAttachmentPath(files); //删除后保留的文件信息
    } else {
      attachmentPath = null; //删除后保留的文件信息
    }

    if (delFunc) {
      delFunc(fileObj.url, attachmentPath);
    }
    fileChange(files, fileObj.url);
  };

  const handleAccept = useMemo(() => {
    let acceptStr: string = '.db';
    if (accept) {
      let newStr = accept?.split('|');
      acceptStr = newStr?.toString();
    }
    return acceptStr;
  }, [accept]);

  /** 上传文件配置 */
  const uploadProps = {
    name: name,
    accept: handleAccept,
    multiple: isMultiple,
    action: baseUrl + url,
    showUploadList: false,
    headers: {
      tenantName: getTenant(),
      busiPath: fieldBusiPath,
      fileType: saveFieldType,
    },
    fileList: fileList,
    maxCount: maxFile,
    beforeUpload: (file: any) => {
      let newAccept = handleAccept;
      let typeCorrect = isTypeCorrect(file, newAccept);
      if (typeCorrect) {
        return true;
      } else {
        if (handleAccept) {
          message.error(`上传格式错误，请上传（${accept}）的文件格式！`);
        } else {
          message.error('上传格式错误，请上传（.doc|.docx|.pdf|.jpg|.png|.jpeg）的文件格式！');
        }
        return false;
      }
    },
    onChange: (info: any) => {
      setUploadLoading(true);
      if (info.file.status === 'done') {
        if (info.file.response) {
          // if (info.file.response.state === 'SUCCESS') {
          if (info.file.response.msgFlag) {
            message.success('文件上传成功');

            // fileList?.forEach((item: any) => {
            //   if (item.uid == info.file.uid) {
            //     item.url = info.file.response.url;
            //     item.original = info.file.response.original;
            //     item.status = 'done';
            //     item.name = info.file.response.title;
            //     item.fileType = info?.file?.response?.type;
            //     item.fileState = info?.file?.response?.state;
            //   }
            // });
            fileList?.forEach((item: any) => {
              if (item.uid == info.file.uid) {
                item.url = info.file.response?.fileURL ? info.file.response?.fileURL : '';
                item.original = info.file.originFileObj ? info.file.originFileObj : '';
                item.status = 'done';
                item.name = info.file.name ? info.file.name : '';
                item.fileType = info?.file?.type ? info?.file?.type : '';
                // item.fileState = info?.file?.response?.obj?.state;
                item.fileState = 'SUCCESS';
              }
            });
            fileChange(fileList, null);
          } else {
            message.error('文件上传错误信息' + info.file.response.msg);
          }
        } else {
          message.error('抱歉，服务器出错了');
        }
        setUploadLoading(false);
      } else if (info.file.status === 'uploading') {
        let file = {
          uid: info.file.uid,
          name: info.file.name,
          status: 'uploading',
          type: info.file.type,
          fileType: info?.file?.response?.obj?.type,
          fileState: info?.file?.response?.obj?.state,
        };
        // let isHave = false;

        let isHave: boolean = fileList?.some((item: any) => {
          return item.uid == file.uid;
        });

        if (!isHave && fileList?.length != maxFile) {
          // let newFileList = deepClone(fileList);
          let newFileList = fileList;
          newFileList.push(file);
          // setFileList(newFileList);
          fileCallback(newFileList);
        }
      } else if (info.file.status === 'error') {
        message.error(`${info.file.name}` + '文件上传失败');
        setUploadLoading(false);
      } else {
        setUploadLoading(false);
      }
    },
  };

  /**  判断是否上传成功的文件列表 */
  const successFileArr = useMemo(() => {
    if (fileList && fileList?.length > 0) {
      let fileArr: any[] = fileList?.filter((item: any) => {
        return item?.fileState == 'SUCCESS';
      });
      return fileArr;
    } else {
      return [];
    }
  }, [fileList, uploadLoading]);

  /** 是否隐藏上传按钮 */
  const isHandUploadBtn = useMemo(() => {
    let isShowFieldList: boolean = false; //是否显示下方文件列，true为显示
    let btnCss: React.CSSProperties = {}; //上传按钮样式
    let fileRowDiv: React.CSSProperties = {}; //文件列表根元素
    let fileRowBorder: React.CSSProperties = {}; //文件列表边框元素
    let fileItemCol: React.CSSProperties = {}; //文件列表 col
    if (maxFile == fileList?.length && fileList?.length == 1) {
      isShowFieldList = true;

      btnCss['display'] = 'none';

      fileRowDiv['marginTop'] = '0px';
      fileRowDiv['marginBottom'] = '0px';
      fileRowDiv['padding'] = '0px';
      fileRowDiv['width'] = '100%';

      fileRowBorder['padding'] = '0px';
      fileRowBorder['border'] = 'none';
      // fileRowBorder["border"] = "1px solid #d9d9d9"
      // fileRowBorder["borderRadius"] = "2px"

      fileItemCol['paddingLeft'] = '0px';
      fileItemCol['paddingRight'] = '0px';
    }
    return {
      btnCss,
      fileRowDiv,
      isShowFieldList,
      fileRowBorder,
      fileItemCol,
    };
  }, [maxFile, fileList?.length]);

  return (
    <>
      <Col>
        <Form.Item
          style={{ margin: '0px', height: '26px', position: 'relative', bottom: '3px' }}
          name={fileFormName}
          label={label}
          rules={[
            {
              required: required,
              message: `请上传${label || '文件'}`,
            },
          ]}
        >
          <>
            <span style={{ ...isHandUploadBtn?.btnCss }}>
              <Upload {...uploadProps}>
                <Button
                  type="link"
                  className="ant-btn ant-btn-link ant-btn-sm manageBtntTxtStyle"
                  disabled={
                    disabledUpload
                      ? true
                      : uploadLoading
                      ? true
                      : successFileArr && successFileArr?.length > 0 && maxFile && maxFile == fileList.length
                      ? true
                      : false
                  }
                  onMouseOut={(event: any) => {
                    event?.target?.nodeName == 'BUTTON' ? event?.target?.blur() : event.target.parentNode.blur();
                  }}
                  loading={uploadLoading}
                >
                  <UploadOutlined />
                  <span>{children || '上传附件'}</span>
                </Button>
              </Upload>
              {/* <Tooltip title={tip ?? returnTooltip()}>
                <a style={{ marginLeft: 8 }}>
                  <QuestionCircleOutlined />
                </a>
              </Tooltip> */}
            </span>
            {successFileArr && successFileArr?.length > 0 && isHandUploadBtn?.isShowFieldList && (
              <div style={{ marginTop: 4, ...isHandUploadBtn?.fileRowDiv }} className={Cls('renderFileBox', classname)}>
                <Row className={fileBoxStyle['updateFile-border']} gutter={[10, 5]} style={{ ...isHandUploadBtn?.fileRowBorder }}>
                  {fileList.map((item: any, index: any) => {
                    if (item.status != 'done') {
                      return '';
                    }
                    // let type = getFileTypeIcon(item.name);
                    let fileNameBox: string = getFileNameNotType(item);

                    return (
                      <Fragment key={index + item?.uid}>
                        <Col
                          span={inRowProportion}
                          style={{
                            // whiteSpace: 'nowrap',
                            ...isHandUploadBtn?.fileItemCol,
                          }}
                          className={pageStyles['over-flow-hidden']}
                        >
                          <div className={fileBoxStyle['fileViewColDiv']}>
                            <Tooltip placement="top" title={item.name}>
                              <a
                                onClick={() => {
                                  message.success('下载中，请稍后...');
                                  if (downloadMethod) {
                                    downloadTemplatePost(downloadUrl, item.name, item.url, () => {}, downloadMethod);
                                  } else {
                                    downloadTemplate(downloadUrl, item.name, item.url, () => {});
                                  }
                                }}
                              >
                                {/* <MyIcon type={type} />&nbsp; */}
                                <span>{fileNameBox}</span>
                              </a>
                            </Tooltip>
                            {/* </Col>
                    <Col span={3} style={{ textAlign: 'center' }}> */}
                            <div>
                              {isEdit && item?.url && (
                                <Tooltip title={'在线预览'}>
                                  <Button
                                    type="link"
                                    size="small"
                                    onClick={() => {
                                      if (onNtkoRead) {
                                        //在线编辑预览
                                        onNtkoRead(item.url);
                                      } else if (onOpenReadOfdWord) {
                                        //轻阅读预览
                                        onOpenReadOfdWord(item.url);
                                      }
                                    }}
                                    icon={<EyeOutlined />}
                                  />
                                </Tooltip>
                              )}
                              <Popconfirm
                                title={'确认要删除吗？删除后无法恢复！'}
                                okText={'确认'}
                                cancelText={'取消'}
                                onConfirm={() => {
                                  deleteFile(item);
                                }}
                              >
                                <Button
                                  // type="link"
                                  type="text"
                                  danger
                                  size="small"
                                  icon={<DeleteOutlined style={{ color: 'red' }} />}
                                />
                                {/* <span>
                              <MyIcon
                                type="icon-delete1"
                                style={{ cursor: 'pointer' }}
                              />
                            </span> */}
                              </Popconfirm>
                            </div>
                          </div>
                        </Col>
                      </Fragment>
                    );
                  })}
                </Row>
              </div>
            )}
          </>
        </Form.Item>

        {successFileArr && successFileArr?.length > 0 && !isHandUploadBtn?.isShowFieldList && (
          <div style={{ marginTop: 4 }} className={Cls('renderFileBox', classname)}>
            <Row className={fileBoxStyle['updateFile-border']} gutter={[10, 5]}>
              {fileList.map((item: any, index: any) => {
                if (item.status != 'done') {
                  return '';
                }
                // let type = getFileTypeIcon(item.name);
                let fileNameBox: string = getFileNameNotType(item);

                return (
                  <Fragment key={index + item?.uid}>
                    <Col
                      span={inRowProportion}
                      // style={{
                      //   whiteSpace: 'nowrap',
                      // }}
                      className={pageStyles['over-flow-hidden']}
                    >
                      <div className={fileBoxStyle['fileViewColDiv']}>
                        <Tooltip placement="top" title={item.name}>
                          <a
                            onClick={() => {
                              message.success('下载中，请稍后...');
                              if (downloadMethod) {
                                downloadTemplatePost(downloadUrl, item.name, item.url, () => {}, downloadMethod);
                              } else {
                                downloadTemplate(downloadUrl, item.name, item.url, () => {});
                              }
                            }}
                          >
                            {/* <MyIcon type={type} />&nbsp; */}
                            <span>{fileNameBox}</span>
                          </a>
                        </Tooltip>
                        {/* </Col>
                    <Col span={3} style={{ textAlign: 'center' }}> */}
                        <div>
                          {isEdit && item?.url && (
                            <Tooltip title={'在线预览'}>
                              <Button
                                type="link"
                                size="small"
                                onClick={() => {
                                  if (onNtkoRead) {
                                    //在线编辑预览
                                    onNtkoRead(item.url);
                                  } else if (onOpenReadOfdWord) {
                                    //轻阅读预览
                                    onOpenReadOfdWord(item.url);
                                  }
                                }}
                                icon={<EyeOutlined />}
                              />
                            </Tooltip>
                          )}
                          <Popconfirm
                            title={'确认要删除吗？删除后无法恢复！'}
                            okText={'确认'}
                            cancelText={'取消'}
                            onConfirm={() => {
                              deleteFile(item);
                            }}
                          >
                            <Button
                              // type="link"
                              type="text"
                              danger
                              size="small"
                              icon={<DeleteOutlined style={{ color: 'red' }} />}
                            />
                            {/* <span>
                              <MyIcon
                                type="icon-delete1"
                                style={{ cursor: 'pointer' }}
                              />
                            </span> */}
                          </Popconfirm>
                        </div>
                      </div>
                    </Col>
                  </Fragment>
                );
              })}
            </Row>
          </div>
        )}

        <Form.Item name={fileFormDelName} initialValue={undefined} noStyle>
          <Input hidden />
        </Form.Item>
      </Col>
    </>
  );
};
